using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Gj.Galaxy.Logic;
// using LeanCloud;
// using LeanCloud.Realtime;
// using TapTap.Bootstrap;
using UnityEngine;

namespace Gj.TapTap
{
    // public interface ImInterface
    // {
    //     void OnConnectSuccess(string channel, int number);
    //     void UpdateUnReadCount(string channel, int number);
    //     void OnMessage(string channel, TDSUser target, string message, bool isSelf);
    //     void OnUpdateList(string prefix, TDSUser[] targets);
    //     void OnList(string prefix, Conversation[] channels);
    //     void OnReconnect();
    //     void OnConnect();
    // }
    //
    // public class Prefix
    // {
    //     public bool IsGlobal; // 全部，势力
    //     public bool IsGroup; // 军团，多人小组
    //     public bool IsPrivate; // 私聊
    //     public bool IsTmp; // 小队，房间
    //     public string Key;
    //     public bool NeedHistory; // 是否加载历时：私聊
    // }
    //
    // public class Conversation
    // {
    //     internal string Channel;
    //     internal LCIMConversation Conv;
    //     internal bool IsConnect;
    //     internal bool IsLoad;
    //     internal bool IsOpen;
    //     internal int MemberCount;
    //     internal List<LCIMMessage> Messages;
    //     internal Prefix Prefix;
    //     internal int ReadIndex;
    //     internal int UnReadCount;
    // }
    //
    // public class Im
    // {
    //     public static LCIMClient ImInstance;
    //     public static ImInterface Delegate;
    //     public static TDSUser CurrentUser;
    //     public static Dictionary<string, LCIMConversation> Channels = new();
    //     public static Dictionary<string, Conversation> ChannelMap = new();
    //     public static Dictionary<string, Prefix> PrefixMap = new();
    //
    //     public static void Register(Prefix prefix)
    //     {
    //         Debug.LogError("register chat prefix:" + prefix.Key);
    //         if (PrefixMap.ContainsKey(prefix.Key)) throw new Exception("has prefix key");
    //         PrefixMap.Add(prefix.Key, prefix);
    //     }
    //
    //     public static async Task Open(string channel)
    //     {
    //         Conversation conv;
    //         if (!ChannelMap.TryGetValue(channel, out conv))
    //         {
    //             conv = await Connect(channel, false);
    //             if (conv == null) return;
    //         }
    //
    //         await conv.Conv.Read();
    //         conv.UnReadCount = 0;
    //         var tmp = conv.ReadIndex;
    //         // 默认打开最多条数
    //         // 日后提供向上加载
    //         if (tmp < conv.Messages.Count - 50) tmp = conv.Messages.Count - 50;
    //         while (tmp < conv.Messages.Count)
    //         {
    //             await OnMessage(conv, conv.Messages[tmp]);
    //             tmp += 1;
    //         }
    //
    //         conv.IsOpen = true;
    //         conv.ReadIndex = tmp;
    //     }
    //
    //     public static Prefix ParseChannel(string channel)
    //     {
    //         var prefixString = channel.Substring(0, channel.IndexOf(":", StringComparison.Ordinal));
    //         Prefix prefix;
    //         Debug.LogError("channel prefix:" + channel + "==>" + prefixString);
    //         if (!PrefixMap.TryGetValue(prefixString, out prefix)) return null;
    //
    //         return prefix;
    //     }
    //
    //     public static async Task<Conversation> Connect(string channel, bool isOpen)
    //     {
    //         Conversation conv;
    //         Debug.LogError("connect1:" + channel);
    //         if (ChannelMap.TryGetValue(channel, out conv))
    //         {
    //             Delegate.OnConnectSuccess(conv.Channel, conv.UnReadCount);
    //             return conv;
    //         }
    //
    //         Debug.LogError("connect2:" + channel);
    //         var prefix = ParseChannel(channel);
    //         if (prefix == null) return null;
    //
    //         Debug.LogError("connect3:" + channel + "->prefix:" + prefix.Key);
    //         conv = new Conversation();
    //         conv.IsConnect = true;
    //         conv.IsOpen = isOpen;
    //         conv.Channel = channel;
    //         conv.Prefix = prefix;
    //         conv.Messages = new List<LCIMMessage>();
    //         ChannelMap.Add(channel, conv);
    //
    //         if (prefix.IsPrivate)
    //         {
    //             Debug.LogError("connect private:" + channel);
    //             await OpenPrivate(conv);
    //         }
    //         else if (prefix.IsGlobal)
    //         {
    //             Debug.LogError("connect global:" + channel);
    //             await JoinChat(conv);
    //         }
    //         else if (prefix.IsGroup)
    //         {
    //             Debug.LogError("connect group:" + channel);
    //             await OpenGroup(conv);
    //         }
    //         else if (prefix.IsTmp)
    //         {
    //             Debug.LogError("connect tmp:" + channel);
    //             await JoinTmp(conv);
    //         }
    //
    //         if (prefix.NeedHistory)
    //         {
    //             Debug.LogError("connect load history:" + channel + "=>" + conv.Conv.Unread);
    //             conv.IsLoad = true;
    //             await _LoadHistory(conv, conv.Conv.Unread + 10);
    //             conv.IsLoad = false;
    //             conv.UnReadCount = conv.Conv.Unread;
    //         }
    //
    //         conv.ReadIndex = 0;
    //         if (isOpen)
    //         {
    //             Debug.LogError("connect open:" + channel);
    //             await Open(channel);
    //         }
    //
    //         Debug.LogError("connect success:" + channel);
    //         Delegate.OnConnectSuccess(conv.Channel, conv.UnReadCount);
    //         return conv;
    //     }
    //
    //     public static void Close(string channel)
    //     {
    //         Conversation conv;
    //         if (!ChannelMap.TryGetValue(channel, out conv)) return;
    //
    //         conv.IsOpen = false;
    //     }
    //
    //
    //     public static async void Leave(string channel)
    //     {
    //         Conversation conv;
    //         if (!ChannelMap.TryGetValue(channel, out conv)) return;
    //
    //         if (conv.Conv != null) await conv.Conv.Quit();
    //         Channels.Remove(channel);
    //     }
    //
    //     public static void Reset()
    //     {
    //         var e = ChannelMap.GetEnumerator();
    //         while (e.MoveNext()) e.Current.Value.ReadIndex = 0;
    //         e.Dispose();
    //     }
    //
    //     public static async Task Init(TDSUser user, ImInterface de)
    //     {
    //         Delegate = de;
    //         CurrentUser = user;
    //         ImInstance = new LCIMClient(user);
    //
    //         async void ImInstanceMessage(LCIMConversation conversation, LCIMMessage msg)
    //         {
    //             // Debug.LogError("onmessage start");
    //             // 查找converstaion
    //             var prefix = ParseChannel(conversation.Name);
    //             var channel = conversation.Name;
    //             if (prefix.IsPrivate)
    //             {
    //                 var other = _parsePrivate(prefix, conversation.Name);
    //                 channel = prefix.Key + ":" + other;
    //             }
    //
    //             Conversation conv;
    //             if (!ChannelMap.TryGetValue(channel, out conv))
    //             {
    //                 conv = await Connect(channel, false);
    //                 if (conv == null) return;
    //             }
    //
    //             // 判断conv是否打开状态
    //             await ImInstanceMessageTask(conv, msg);
    //             // Debug.LogError("onmessage success");
    //         }
    //
    //         ImInstance.OnMessage = ImInstanceMessage;
    //
    //         async void ImInstanceInvited(LCIMConversation conversation, string s)
    //         {
    //             var prefix = ParseChannel(conversation.Name);
    //             var channel = conversation.Name;
    //             if (prefix.IsPrivate)
    //             {
    //                 var other = _parsePrivate(prefix, conversation.Name);
    //                 channel = prefix.Key + ":" + other;
    //             }
    //
    //             Conversation conv;
    //             if (ChannelMap.TryGetValue(channel, out conv)) return;
    //             Debug.LogError("oninvited can：" + conversation.Name);
    //             await Connect(channel, false);
    //         }
    //
    //         ImInstance.OnInvited = ImInstanceInvited;
    //         ImInstance.OnPaused = () => { Delegate.OnReconnect(); };
    //         ImInstance.OnResume = () => { Delegate.OnConnect(); };
    //         await ImInstance.Open();
    //         Delegate.OnConnect();
    //     }
    //
    //     public static async Task GetList(Prefix prefix)
    //     {
    //         try
    //         {
    //             var query = new LCIMConversationQuery(ImInstance);
    //             query.WhereEqualTo("tr", prefix.IsGlobal);
    //             query.WhereEqualTo(prefix.Key, true);
    //             var room = await query.Find();
    //             var e = room.GetEnumerator();
    //             var roomIds = new Conversation[room.Count];
    //             var i = 0;
    //             while (e.MoveNext())
    //             {
    //                 var conv = e.Current;
    //                 var channel = conv.Name;
    //                 if (!ChannelMap.TryGetValue(channel, out var conversation))
    //                 {
    //                     conversation = new Conversation();
    //                     conversation.Prefix = prefix;
    //                     conversation.Channel = channel;
    //                     conversation.Conv = conv;
    //                 }
    //
    //                 conversation.MemberCount = await conversation.Conv.GetMembersCount();
    //                 roomIds[i] = conversation;
    //                 i++;
    //             }
    //
    //             e.Dispose();
    //             Delegate.OnList(prefix.Key, roomIds);
    //         }
    //         catch (LCException e)
    //         {
    //             Debug.Log($"encounter exception:{e.Code} message:{e}");
    //             Debug.LogException(e);
    //         }
    //     }
    //
    //     public static async Task UpdateList(Prefix prefix)
    //     {
    //         if (!prefix.IsPrivate) return;
    //         try
    //         {
    //             var query = new LCIMConversationQuery(ImInstance);
    //             query.WhereEqualTo("tr", false);
    //             query.WhereEqualTo(prefix.Key, true);
    //             var members = new List<string> { CurrentUser.ObjectId };
    //             query.WhereContainedIn("m", members);
    //             query.OrderByDescending("updateAt");
    //             var room = await query.Find();
    //             var e = room.GetEnumerator();
    //             var userIds = new List<string>();
    //             var i = 0;
    //             while (e.MoveNext())
    //             {
    //                 var conversation = e.Current;
    //                 var channel = conversation.Name;
    //                 var other = _parsePrivate(prefix, channel);
    //                 if (string.IsNullOrEmpty(other)) continue;
    //                 channel = prefix.Key + ":" + other;
    //                 var conv = await Connect(channel, false);
    //                 if (conv == null) continue;
    //
    //                 userIds.Add(other);
    //
    //                 i++;
    //             }
    //
    //             e.Dispose();
    //             var tdsUser = await User.GetUsers(userIds.ToArray());
    //             Delegate.OnUpdateList(prefix.Key, tdsUser);
    //         }
    //         catch (LCException e)
    //         {
    //             Debug.Log($"encounter exception:{e.Code} message:{e}");
    //             Debug.LogException(e);
    //         }
    //     }
    //
    //     private static async Task ImInstanceMessageTask(Conversation conv, LCIMMessage msg)
    //     {
    //         conv.Messages.Add(msg);
    //         if (conv.IsLoad) return;
    //         if (!conv.IsOpen)
    //         {
    //             conv.UnReadCount += 1;
    //             Delegate.UpdateUnReadCount(conv.Channel, conv.UnReadCount);
    //             return;
    //         }
    //
    //         conv.ReadIndex = conv.Messages.Count;
    //         await OnMessage(conv, msg);
    //     }
    //
    //     private static async Task OnMessage(Conversation conv, LCIMMessage msg)
    //     {
    //         // await _(conv);
    //         {
    //             var tdsUser = await User.GetUser(msg.FromClientId);
    //             var player = AuthConnect.factory.OnJoin(Convert.ToString(tdsUser["openid"]));
    //             if (player != null) await player.Init();
    //             var isSelf = msg.FromClientId == CurrentUser.ObjectId;
    //             if (msg is LCIMTextMessage textMessage)
    //             {
    //                 Debug.LogError("conv message " + conv.Channel + ":" + tdsUser + ":" + textMessage.Text);
    //                 Delegate.OnMessage(conv.Channel, tdsUser, textMessage.Text, isSelf);
    //             }
    //         }
    //     }
    //
    //     // 创建私人对话
    //     public static async Task OpenPrivate(Conversation conv)
    //     {
    //         LCIMConversation conversation;
    //         var target = conv.Channel.Replace(conv.Prefix.Key + ":", "");
    //         try
    //         {
    //             conversation = await ImInstance.CreateConversation(new[] { target },
    //                 conv.Prefix.Key + ":/" + target + "/" + CurrentUser.ObjectId + "/", true,
    //                 new Dictionary<string, object> { { conv.Prefix.Key, true } });
    //             conv.Conv = conversation;
    //         }
    //         catch (LCException e)
    //         {
    //             Debug.Log($"encounter exception:{e.Code} message:{e}");
    //             Debug.LogException(e);
    //         }
    //     }
    //
    //     public static async Task OpenGroup(Conversation conv)
    //     {
    //         try
    //         {
    //             var query = new LCIMConversationQuery(ImInstance);
    //             query.WhereEqualTo("tr", false);
    //             query.WhereEqualTo(conv.Prefix.Key, true);
    //             query.WhereEqualTo("name", conv.Channel);
    //             try
    //             {
    //                 var room = await query.First();
    //                 Debug.LogError("find channel:" + conv.Channel);
    //                 if (!room.MemberIds.Contains(CurrentUser.ObjectId)) await room.Join();
    //                 conv.Conv = room;
    //             }
    //             catch (Exception e)
    //             {
    //                 Debug.LogError("chat channel miss:" + conv.Channel + e);
    //                 var room = await ImInstance.CreateConversation(new string[] { }, conv.Channel, false,
    //                     new Dictionary<string, object> { { conv.Prefix.Key, true } });
    //                 if (!room.MemberIds.Contains(CurrentUser.ObjectId)) await room.Join();
    //                 conv.Conv = room;
    //             }
    //         }
    //         catch (LCException e)
    //         {
    //             Debug.Log($"encounter exception:{e.Code} message:{e}");
    //             Debug.LogException(e);
    //         }
    //     }
    //
    //     public static async Task JoinChat(Conversation conv)
    //     {
    //         try
    //         {
    //             var query = new LCIMConversationQuery(ImInstance);
    //             query.WhereEqualTo("tr", true);
    //             query.WhereEqualTo(conv.Prefix.Key, true);
    //             query.WhereEqualTo("name", conv.Channel);
    //             try
    //             {
    //                 var room = await query.First();
    //                 Debug.LogError("find channel:" + conv.Channel);
    //                 // await room.Join();
    //                 if (!room.MemberIds.Contains(CurrentUser.ObjectId)) await room.Join();
    //                 conv.Conv = room;
    //             }
    //             catch (Exception e)
    //             {
    //                 Debug.LogError("chat channel miss:" + conv.Channel + e);
    //                 var room = await ImInstance.CreateChatRoom(conv.Channel,
    //                     new Dictionary<string, object> { { conv.Prefix.Key, true } });
    //                 if (!room.MemberIds.Contains(CurrentUser.ObjectId)) await room.Join();
    //                 conv.Conv = room;
    //             }
    //         }
    //         catch (LCException e)
    //         {
    //             Debug.Log($"encounter exception:{e.Code} message:{e}");
    //             Debug.LogException(e);
    //         }
    //     }
    //
    //     public static async Task JoinTmp(Conversation conv)
    //     {
    //         try
    //         {
    //             var query = new LCIMConversationQuery(ImInstance);
    //             query.WhereEqualTo("tr", false);
    //             query.WhereEqualTo(conv.Prefix.Key, true);
    //             query.WhereEqualTo("name", conv.Channel);
    //             try
    //             {
    //                 var room = await query.First();
    //                 Debug.LogError("find channel:" + conv.Channel);
    //                 if (!room.MemberIds.Contains(CurrentUser.ObjectId)) await room.Join();
    //                 conv.Conv = room;
    //             }
    //             catch (Exception e)
    //             {
    //                 Debug.LogError("chat channel miss:" + conv.Channel + e);
    //                 var room = await ImInstance.CreateConversation(new string[] { }, conv.Channel, false,
    //                     new Dictionary<string, object> { { conv.Prefix.Key, true } });
    //                 if (!room.MemberIds.Contains(CurrentUser.ObjectId)) await room.Join();
    //                 conv.Conv = room;
    //             }
    //         }
    //         catch (LCException e)
    //         {
    //             Debug.Log($"encounter exception:{e.Code} message:{e}");
    //             Debug.LogException(e);
    //         }
    //     }
    //
    //     private static string _parsePrivate(Prefix prefix, string name)
    //     {
    //         name = name.Replace(prefix.Key + ":/", "");
    //         var l = name.Split("/");
    //         if (l[0] == CurrentUser.ObjectId)
    //             name = l[1];
    //         else
    //             name = l[0];
    //
    //         return name;
    //     }
    //
    //     private static async Task _LoadHistory(Conversation conv, int number)
    //     {
    //         var messages = await conv.Conv.QueryMessages(limit: number);
    //         foreach (var message in messages) await ImInstanceMessageTask(conv, message);
    //         // if (message is LCIMTextMessage textMessage) {
    //         //     Delegate.OnMessage(room.Name, textMessage.FromClientId, textMessage.Text);
    //         // }
    //     }
    //
    //     public static async Task Send(string channel, string content,
    //         LCIMMessagePriority priority = LCIMMessagePriority.Normal)
    //     {
    //         if (string.IsNullOrEmpty(content)) return;
    //
    //         Conversation conv;
    //         if (!ChannelMap.TryGetValue(channel, out conv))
    //         {
    //             conv = await Connect(channel, false);
    //             if (conv == null) return;
    //         }
    //
    //         var message = new LCIMTextMessage(content);
    //         var options = new LCIMMessageSendOptions
    //         {
    //             Transient = false,
    //             Receipt = false,
    //             Priority = priority,
    //             Will = false
    //         };
    //         var msg = await conv.Conv.Send(message);
    //         Debug.LogError("message:" + msg.Id + "->" + msg.ConversationId);
    //         await ImInstanceMessageTask(conv, msg);
    //     }
    // }
}